﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;

using eBook.Core;
using eBook.Core.BusinessObjects;
using eBook.Core.Contracts;



using PragmaTouchUtils;
using System.Text.RegularExpressions;

namespace eBook.WinApp
{

  public static class Utils
  {
    public static ContextOptions ContextOptions { get { return ConfigContent.Current.GetConfigContentItem("ContextOptions") as ContextOptions; } }
    public static DatabaseOptions DatabaseOptions { get { return ConfigContent.Current.GetConfigContentItem("DatabaseOptions") as DatabaseOptions; } }
    public static FolderOptions FolderOptions { get { return ConfigContent.Current.GetConfigContentItem("FolderOptions") as FolderOptions; } }
    public static WebDataProviderOptions WebDataProviderOptions { get { return ConfigContent.Current.GetConfigContentItem("WebDataProviderOptions") as WebDataProviderOptions; } }

    public static string ReplaceInvalidFilenameChar(string filename)
    {
      string result = new Regex(@"[:\\/?<>|\*]").Replace(filename, " ");
      return result;
    }

    public static DataGridView FormatGrid(DataGridView grd, bool autoGenerateColumns = false)
    {
      grd.AllowUserToAddRows = false;
      grd.AllowUserToDeleteRows = false;
      grd.AllowUserToOrderColumns = true;
      grd.AllowUserToResizeColumns = true;
      grd.AllowUserToResizeRows = false;
      grd.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;

      grd.AutoGenerateColumns = autoGenerateColumns;
      grd.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
      grd.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
      grd.BackgroundColor = Color.FromKnownColor( KnownColor.AppWorkspace );
      grd.BorderStyle = BorderStyle.Fixed3D;
      grd.Font = new Font(new FontFamily("Calibri"), 9.75f);

      //grd.ReadOnly = true;      
      grd.RowHeadersVisible = false;
      grd.MultiSelect = false;

      ContextMenuStrip m = Utils.BuildGridContextMenu(grd);
      if (grd.ContextMenuStrip != null)
      {
        grd.ContextMenuStrip.Items.Add(new ToolStripSeparator());
        grd.ContextMenuStrip.Items.AddRange(m.Items);
      }
      else
        grd.ContextMenuStrip = Utils.BuildGridContextMenu(grd);

      return grd;    
    }
    
    private static int _menuCounter;
    public static ContextMenuStrip BuildGridContextMenu(DataGridView grd)
    {
      ContextMenuStrip menu = new ContextMenuStrip();      
      menu.Name = string.Format("mnu{0}_{1}", grd.Name, _menuCounter++);
      //menu.Size = new System.Drawing.Size(155, 70);

      ToolStripMenuItem mnuExcelExport = new ToolStripMenuItem();
      mnuExcelExport.Name = string.Format("{0}_ExcelExport", menu.Name);
      mnuExcelExport.Size = new System.Drawing.Size(154, 22);
      mnuExcelExport.Text = "Export to Excel";
      mnuExcelExport.Click += new EventHandler( (sender, e) => Utils.ExportToExcel(grd) );

      menu.Items.AddRange(new ToolStripItem[] { mnuExcelExport });

      return menu;
    }


    



    private static string[] _excelColumnNames= new string[78] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" 
                                                    , "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AW", "AX", "AY", "AZ" 
                                                    , "BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BK", "BL", "BM", "BN", "BO", "BP", "BQ", "BR", "BS", "BT", "BU", "BV", "BW", "BX", "BY", "BZ" };


    public static void ExportToExcel(DataGridView grd)
    {
      if ( grd.ColumnCount - 1 > _excelColumnNames.Count() )
        throw new ArgumentOutOfRangeException("Grid column count", "Number of columns exceeds the internal map capacity.");

      if (grd.RowCount <= 0)
        return;

      Excel.Application excel = null;
      Excel.Workbook workbook  = null;
      Excel.Worksheet worksheet = null;
      try
      {
        excel = new Excel.Application();

        workbook = excel.Workbooks.Add(System.Reflection.Missing.Value);
        worksheet = ( Excel.Worksheet ) workbook.ActiveSheet;
        worksheet.Name = grd.Name;

        string bottomRight = string.Format("{0}{1}", _excelColumnNames[grd.ColumnCount - 1], grd.RowCount + 1);
        string range = string.Format("A1:{0}", bottomRight);
        worksheet.get_Range(range, Type.Missing).Value2 = CreateTwoDimensionalObject(grd);
        
        worksheet.get_Range("A1", bottomRight).EntireColumn.AutoFit();
        worksheet.get_Range("A1", bottomRight).RowHeight = 16;
        worksheet.get_Range("A1", bottomRight).Rows.VerticalAlignment = 2;
        excel.Visible = true;
      }
      catch
      {
        if ( excel != null )        
          excel.Quit();
        
        throw;
      }
			finally
			{
        if (worksheet != null) 
          Marshal.ReleaseComObject(worksheet);

				if (workbook != null) 
          Marshal.ReleaseComObject(workbook);

        if (excel != null)				
					Marshal.ReleaseComObject(excel);

        worksheet = null;
				workbook  = null;        
				excel     = null;
			}
    }

    //creates the two dimensional object[,] from the datagridview
    private static object[,] CreateTwoDimensionalObject(DataGridView grd)
    {
      object[,] data = new object[grd.Rows.Count + 1, grd.Rows[0].Cells.Count];

      //add the first row(the column headers) to the array
      for (int col = 0; col < grd.Columns.Count; col++)      
        data[0, col] = grd.Columns[col].HeaderText;      

      //copy the actual data
      for (int col = 0; col < grd.Rows[0].Cells.Count; col++)      
        for (int row = 0; row < grd.Rows.Count; row++)        
          if (grd.Rows[row].Cells[col].Value != null)
            data[row + 1, col] = grd.Rows[row].Cells[col].Value.ToString();
              
      return data;
    }







  }
}
